// 官方
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n, m;
  cin >> n >> m;
  bool f[10][10] = {}; // 原始图的邻接矩阵，初始化为false
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--; // 转换为0-based索引
    if (u > v)
      swap(u, v);   // 统一存储，保证u < v
    f[u][v] = true; // 标记原始图中的边
  }

  int ans = 100;    // 初始化一个大值，用于记录最小修改次数
  vector<int> a(n); // 用于生成排列的数组
  for (int i = 0; i < n; i++)
    a[i] = i; // 初始化排列为0,1,2,...,n-1

  do { // 枚举所有顶点排列
    // 情况1：整个图是一个大环
    bool g[10][10] = {}; // 目标图的邻接矩阵
    for (int i = 0; i < n; i++) {
      int u = a[i], v = a[(i + 1) % n]; // 环中相邻顶点
      if (u > v)
        swap(u, v);
      g[u][v] = true; // 标记目标图中的边
    }
    // 计算需要修改的边数（异或结果为1表示需要修改）
    int c0 = 0;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        c0 += f[i][j] ^ g[i][j];
    ans = min(ans, c0); // 更新最小修改次数

    // 情况2：图分为两个环
    for (int d = 3; d <= n - 3; d++) { // 第一个环大小d，第二个环大小n-d
      bool h[10][10] = {};             // 双环情况的目标图
      // 构建第一个环
      for (int i = 0; i < d; i++) {
        int u = a[i], v = a[(i + 1) % d];
        if (u > v)
          swap(u, v);
        h[u][v] = true;
      }
      // 构建第二个环
      for (int i = 0; i < n - d; i++) {
        int u = a[i + d], v = a[(i + 1) % (n - d) + d];
        if (u > v)
          swap(u, v);
        h[u][v] = true;
      }
      // 计算需要修改的边数
      int c1 = 0;
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          c1 += f[i][j] ^ h[i][j];
      ans = min(ans, c1); // 更新最小修改次数
    }
  } while (next_permutation(a.begin(), a.end())); // 生成下一个排列

  cout << ans << '\n'; // 输出最小修改次数
}
